/************************************************************************
This file is part of Polar4linux
Copyright (C) 2010-2011 Eric jrdn2
Portions Copyright (C) 2007 Matti Juvonen <mpj@iki.fi> (RS400 Tools)
Portions Copyright (C) 2006 Jani Hursti <jani.hursti@hut.fi>,
Portions Copyright (C) 2001-2003 Tom Oliveira e Silva

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
************************************************************************/

#include "polarStatistics.h"

polarStatistics::polarStatistics(polar4linuxInternals *internals0)
{
	internals=internals0;
	setupUi(this);
	view->associate(internals);
	g=new yearStatsGraph(&internals->default_graph_configuration);
	view->addGraph(g);
	int year=QDate::currentDate().year();
	QDate begin(year,1,1);
	QDate end(year+1,1,1);
	dateEditStart->setDate(begin);
	dateEditEnd->setDate(end);
	connect(dateEditStart,SIGNAL(dateChanged(const QDate&)), this, SLOT(boundsChanged()));
	connect(dateEditEnd,SIGNAL(dateChanged(const QDate&)), this, SLOT(boundsChanged()));
	connect(comboBoxStatType,SIGNAL(currentIndexChanged ( int )), this, SLOT(boundsChanged()));
	//show();
}

polarStatistics::~polarStatistics()
{
	//delete g; //no! g is deleted during view dtor
}

void polarStatistics::computeStatistics()
{
	g->totalTime=0;
	g->NumExercises=0;
	g->averageTime=0;
	g->averageHR=0;
	g->totalCalories=0;
	g->averageStartTime=0;
	g->maxtimeWeek=0;
	g->SportzoneBars.clear();
	g->HRaverages.clear();
	g->startTimes.clear(); for (unsigned int i=0;i<24*2;i++) g->startTimes.push_back(0);
	g->durations.clear();  for (unsigned int i=0;i<10*6;i++) g->durations.push_back(0);
	g->HRates.clear();     for (unsigned int i=0;i<40;i++) g->HRates.push_back(0);
	
	int numdays=g->startDate.daysTo(g->endDate);
	if (numdays<0) return;

	//always start on monday
	int dayofweek=g->startDate.dayOfWeek();
	QDate thedate(g->startDate.addDays(-dayofweek+1));
	numdays+=dayofweek-1;

	QDate thedate2;

	rs400_pdd_content toto;
	//int week=0;

	for (int nb=0;nb<numdays+1;nb+=7)
	{
		statisticsSportzone statBar;
		for (int i=0;i<10;i++) statBar.timeInZones[i]=0;
		statBar.weekTime=0;
		int nbExercisesThisWeek=0;
		int avHRthisWeek=0;
		for (int i=0;i<7;i++)
		{
			thedate2=thedate.addDays(i);
			QString disp=internals->data_path+thedate2.toString("yyyyMMdd")+".pdd";

			int intStat = checkFileExistence(disp.toStdString().c_str()); 
			if (intStat==0 && thedate2>=g->startDate && thedate2<=g->endDate)
			{
				_readPDD( (char*)disp.toStdString().c_str(), toto);
				for (unsigned int j=0;j<toto.dayinfo.nbrExercises;j++)
				{
					statBar.timeInZones[0]+=toto.exerciseinfo[j].zone0Time;
					statBar.timeInZones[1]+=toto.exerciseinfo[j].zone1Time;
					statBar.timeInZones[2]+=toto.exerciseinfo[j].zone2Time;
					statBar.timeInZones[3]+=toto.exerciseinfo[j].zone3Time;
					statBar.timeInZones[4]+=toto.exerciseinfo[j].zone4Time;
					statBar.timeInZones[5]+=toto.exerciseinfo[j].zone5Time;
					g->totalCalories+=toto.exerciseinfo[j].energy;
					g->averageStartTime+=toto.exerciseinfo[j].startTime;
					
					int posStartTime=toto.exerciseinfo[j].startTime/(0.5*3600.0); //30 min
					g->startTimes.at(posStartTime)+=1;
					
					int posDuration=toto.exerciseinfo[j].totalTime/(3600.0/6.0); //10 min 
					g->durations.at(posDuration)+=1;
					
					float segSize=internals->default_graph_configuration.user_hr_max/40.0;
					int posHR=toto.exerciseinfo[j].HRaverage/segSize;
					g->HRates.at(posHR)+=1;
					
					nbExercisesThisWeek+=1;
					avHRthisWeek+=toto.exerciseinfo[j].HRaverage;
				}
			}
		}
		if (nbExercisesThisWeek!=0)
		{
			g->averageHR+=avHRthisWeek;
			g->NumExercises+=nbExercisesThisWeek;
			avHRthisWeek/=(float)nbExercisesThisWeek;
		}

		statBar.weekTime=statBar.timeInZones[0]+statBar.timeInZones[1]+statBar.timeInZones[2]
		+statBar.timeInZones[3]+statBar.timeInZones[4]+statBar.timeInZones[5];

		g->totalTime+=statBar.weekTime;

		g->SportzoneBars.push_back(statBar);
		g->HRaverages.push_back(avHRthisWeek);
		if (statBar.weekTime>g->maxtimeWeek) g->maxtimeWeek=statBar.weekTime;
		thedate=thedate.addDays(7);
	}

	if (g->NumExercises!=0)
	{
		g->averageTime=g->totalTime/(float)g->NumExercises;
		g->averageHR=g->averageHR/(float)g->NumExercises;
		g->averageStartTime=g->averageStartTime/(float)g->NumExercises;
	}
	
	//normalize psf
	float max=0;
	for (unsigned int i=0;i<g->startTimes.size();i++) if (g->startTimes[i]>max) max=g->startTimes[i];
	for (unsigned int i=0;i<g->startTimes.size();i++) g->startTimes[i]/=max;
	
	max=0;
	for (unsigned int i=0;i<g->durations.size();i++) if (g->durations[i]>max) max=g->durations[i];
	for (unsigned int i=0;i<g->durations.size();i++) g->durations[i]/=max;
	
	max=0;
	for (unsigned int i=0;i<g->HRates.size();i++) if (g->HRates[i]>max) max=g->HRates[i];
	for (unsigned int i=0;i<g->HRates.size();i++) g->HRates[i]/=max;
	
	//remove wrong points
	g->startTimes[0]=0;
	g->durations[0]=0;
	g->HRates[0]=0;
}


void polarStatistics::boundsChanged()
{
	g->startDate=dateEditStart->date();
	g->endDate=dateEditEnd->date();
	g->type=comboBoxStatType->currentIndex();
	computeStatistics();
	plot();
}

void polarStatistics::plot()
{
	view->plotPage();
}
